package remoting.grpc;

import common.exception.RemotingException;
import common.model.Codec2;
import common.model.MagicUrl;
import common.util.NetUtils;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import java.net.InetSocketAddress;
import remoting.AbstractClient;
import remoting.channel.Channel;
import remoting.channel.ChannelHandler;

public class GrpcClient extends AbstractClient {

  private volatile GreeterGrpc.GreeterStub greeterStub;

  private volatile ManagedChannel managedChannel;

  public GrpcClient(MagicUrl url, ChannelHandler handler, Codec2 codec)
      throws RemotingException {
    super(url, handler, codec);
  }

  @Override
  protected void doOpen() throws Throwable {
    managedChannel = ManagedChannelBuilder.forAddress(getUrl().getHost(),
        getUrl().getPort()).usePlaintext().build();
  }


  @Override
  protected void doConnect() throws Throwable {
    greeterStub = GreeterGrpc.newStub(managedChannel);
  }

  @Override
  protected void doDisConnect() throws Throwable {
    managedChannel.shutdown();

  }

  @Override
  protected void doClose() throws Throwable {
    managedChannel.shutdownNow();
  }

  @Override
  protected Channel getChannel() {
    GreeterGrpc.GreeterStub c = greeterStub;
    if (c == null) {
      return null;
    }
    Channel channel = GrpcClientChannel.getOrAddChannel(c, getUrl(), this, getCodec());
    ((GrpcClientChannel) channel).setRemoteAddress(new InetSocketAddress(NetUtils.filterLocalHost(getUrl().getHost()), getUrl().getPort()));
    return channel;
  }
}
